package com.lw.conexecutor.demo;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**Executor 和 ExecutorService
 *  ExecutorService 是子类
 *  Executor 的execute()方法【无返回值】接收一个Runnable接口的对象
 * ExecutorService的submit()方法【通过一个 Future 对象返回运算结果】接受Runnable和Callable接口的对象。
 * ExecutorService 还提供用来控制线程池的方法===shutDown() 方法终止线程池
 * Executors提供了工厂可以创建四种线程池
 */
public class CallableDemo{
    public static void main(String[] args){
        //创建一个缓存型池子（用于执行一些生存期很短的异步型任务）
        /**因为ThreadPoolExecutor参数众多，且意义重大，未免配错，所以有了下面的工厂方法
         *
         * newCachedThreadPool()    缓存型池子通常用于执行一些生存期很短的异步型任务（适用于执行很多短期异步任务的小程序，或者是负载较轻的服务器。）
         * newFixedThreadPool(int)  固定线程线程池（适用于为了满足资源管理的需求，而需要适当限制当前线程数量的情景，适用于负载比较重的服务器。）
         * SingleThreadExecutor()   单例线程，任意时间池中只能有一个线程（常用于需要让线程顺序执行，并且在任意时间，只能有一个任务被执行，而不能有多个线程同时执行的场景。）
         *
         * newScheduledThreadPool(int)  调度型线程池（适用于若干个（固定）线程延时或者定期执行任务，同时为了满足资源管理的需求而需要限制后台线程数量的场景。）
         * newSingleThreadScheduledExecutor 单线程调度执行器（适用于需要单个线程延时或者定期的执行任务，同时需要保证各个任务顺序执行的应用场景。）
         */
        ExecutorService executorService = Executors.newCachedThreadPool();
        List<Future<String>> resultList = new ArrayList<Future<String>>();
  
        //创建10个任务并执行   
        for (int i = 0; i < 10; i++){   
            //使用ExecutorService执行Callable类型的任务，并将结果保存在future变量中   
            Future<String> future = executorService.submit(new TaskWithResult(i));   
            //将任务执行结果存储到List中   
            resultList.add(future);   
        }   
  
        //遍历任务的结果   
        for (Future<String> fs : resultList){
                try{   
                    while(!fs.isDone());//Future返回如果没有完成，则一直循环等待，直到Future返回完成
                    System.out.println(fs.get());     //打印各个线程（任务）执行的结果   
                }catch(InterruptedException e){   
                    e.printStackTrace();   
                }catch(ExecutionException e){
                    e.printStackTrace();   
                }finally{   
                    //启动一次顺序关闭，执行以前提交的任务，但不接受新任务  
                    executorService.shutdown();   
                }   
        }   
    }   
}   
  
  
class TaskWithResult implements Callable<String> {
    private int id;   
  
    public TaskWithResult(int id){   
        this.id = id;   
    }   
  
    /**  
     * 任务的具体过程，一旦任务传给ExecutorService的submit方法， 
     * 则该方法自动在一个线程上执行 
     */   
    public String call() throws Exception {  
        System.out.println("call()方法被自动调用！！！    " + Thread.currentThread().getName());   
        //该返回结果将被Future的get方法得到  
        return "call()方法被自动调用，任务返回的结果是：" + id + "    " + Thread.currentThread().getName();   
    }   
}